home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / demos / OpenGL / space / ringworld.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  23KB  |  752 lines

  1. /*
  2.  * Copyright (C) 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <GL/gl.h>
  19. #include <math.h>
  20. #include "space.h"
  21.  
  22. #define LOWER_TRI        1
  23. #define UPPER_TRI        2
  24. #define BOTHH_TRI        3
  25.  
  26. #define LEVEL_SEA        1.0000
  27. #define LEVEL_SNOW       0.9995
  28.  
  29. #define MAT_SEABLUE      0 
  30. #define MAT_DIRT         1 
  31. #define MAT_WHITE        2 
  32. #define SUM_WHITE        6 
  33. #define SUM_SEABLUE      0 
  34.  
  35. #define SUBDIVIDE(aa,bb,cc)                    \
  36.          x = (aa)->plan.x + (bb)->plan.x ;             \
  37.          y = (aa)->plan.y + (bb)->plan.y ;             \
  38.          z = (aa)->plan.z + (bb)->plan.z ;             \
  39.          w = fsqrt(x*x+z*z) ;                    \
  40.                                 \
  41.          (cc)->seed = (aa)->seed + (bb)->seed ;            \
  42.          srand((cc)->seed) ;                    \
  43.          s = rand() - 16384 ;                    \
  44.          (cc)->delta = 0.5*((aa)->delta+(bb)->delta) + rg*(flot32)s ;\
  45.          w = (cc)->delta / w;                    \
  46.                                 \
  47.          (cc)->plan.x = w*x ;                    \
  48.          (cc)->plan.y = 0.5*y ;                    \
  49.          (cc)->plan.z = w*z ;                    \
  50.  
  51. typedef struct  {
  52.        sint32 ar,ag,ab   ;
  53.        flot32 dr,dg,db   ; 
  54. } C6 ;
  55.  
  56. static C6 a_dirt,a_seab,a_whit ;
  57.  
  58. typedef struct  {               /* 128 BYTES */
  59.        P3        p ;
  60.        uint32    seed ;    
  61.        sint16    valid ;
  62.        sint16    quadw ;
  63.        sint32    level ;
  64.        sint32    sidsz ;
  65.        TrigPoint *sur ;
  66.        P3        pp[8] ;
  67. } P5 ;
  68.  
  69. extern P4      feye ;
  70. extern V4      plum[NUM_CLIP_PLANES] ;
  71. extern t_stopwatch Counter ;
  72.  
  73. static sint32  dbg[8] ;
  74. static flot32  roughness = 0.0 ;
  75. static sint32  C ;
  76. static P5      dt[2][1025] ;
  77. static struct  { sint32 status,xi,yi,flag ; }  status ;
  78.  
  79. static void   fract_mid(sint32,sint32,flot32) ;
  80. static void   create_continent(P5 *,sint32,sint32) ;
  81. static void   destroy_continent(P5 *) ;
  82. static sint32 clipp(P5 *) ;
  83. static void   land_generation(P5 *,sint32) ;
  84. static void   water_conversion(P5 *,sint32) ; 
  85. static void   generate_shades(P5 *,sint32) ; 
  86. static void   cpack_continent(P5 *,uint32) ;
  87. static void   p_trigpoint(TrigPoint *) ;
  88. static void   p_continent(P5 *) ;
  89.  
  90. /**********************************************************************
  91. *  fract_mid()  -
  92. **********************************************************************/
  93. static void fract_mid(sint32 x1,sint32 x2,flot32 rough)
  94.  
  95. {  register sint32  xi,s,seed ;
  96.    register flot32  x,y,z,w[4] ;
  97.    register P5      *d,*d1,*d2 ;
  98.    register P4      p ;
  99.  
  100.    xi = (x1 + x2) >> 1 ;
  101.  
  102.    d  = &dt[0][xi] ;
  103.    d1 = &dt[0][x1] ;
  104.    d2 = &dt[0][x2] ;
  105.  
  106.    x = d1->p.x + d2->p.x ;
  107.    y = d1->p.y + d2->p.y ;
  108.    z = d1->p.z + d2->p.z ;
  109.    w[0] = fsqrt(x*x+z*z) ;
  110.  
  111.    w[1] = fsqrt(d1->p.x*d1->p.x + d1->p.z*d1->p.z) ;
  112.    w[2] = fsqrt(d2->p.x*d2->p.x + d2->p.z*d2->p.z) ;
  113.    d->seed = d1->seed + d2->seed ;
  114.    srand(d->seed) ;
  115.    s = rand() - 26000 ;
  116.  
  117.    w[3] = (0.5*(w[1]+w[2]) + rough*(float)s/16384.0) / w[0] ;
  118.  
  119.    d->p.x = w[3]*x ;
  120.    d->p.y = 0.5*y ;
  121.    d->p.z = w[3]*z ;
  122.  
  123.    d  = &dt[1][xi] ;
  124.    d1 = &dt[1][x1] ;
  125.    d2 = &dt[1][x2] ;
  126.  
  127.    x = d1->p.x + d2->p.x ;
  128.    y = d1->p.y + d2->p.y ;
  129.    z = d1->p.z + d2->p.z ;
  130.    w[0] = fsqrt(x*x+z*z) ;
  131.  
  132.    w[1] = fsqrt(d1->p.x*d1->p.x + d1->p.z*d1->p.z) ;
  133.    w[2] = fsqrt(d2->p.x*d2->p.x + d2->p.z*d2->p.z) ;
  134.    d->seed = d1->seed + d2->seed ;
  135.    srand(d->seed) ;
  136.    seed = rand() - 16384 ;
  137.    s += seed >> 2 ;
  138.  
  139.    w[3] = (0.5*(w[1]+w[2]) + rough*(float)s/16384.0) / w[0] ;
  140.  
  141.    d->p.x = w[3]*x ;
  142.    d->p.y = 0.5*y ;
  143.    d->p.z = w[3]*z ;
  144. }
  145.  
  146. /**********************************************************************
  147. *  generate_ringworld()  -
  148. **********************************************************************/
  149. void generate_ringworld(sint32 in_level,sint32 in_seed) 
  150.  
  151. {  register flot32  x,y,z,w,e,delta0,delta1,delta2,delta3 ;
  152.    register sint32  i,j,stage,step,dstep ;
  153.    register P4      q ;
  154.    register P5      *d,*p0,*p1,*p2,*p3 ;
  155.    register P3      *pp ;
  156.  
  157.    roughness = 0.0003;
  158.  
  159.    a_dirt.ar = 5; a_dirt.ag = 4; a_dirt.ab = 2; a_dirt.dr = 155.0; a_dirt.dg = 140.0; a_dirt.db =  70.0; 
  160.    a_seab.ar = 0; a_seab.ag = 0; a_seab.ab = 5; a_seab.dr =   0.0; a_seab.dg =   0.0; a_seab.db = 224.0; 
  161.    a_whit.ar = 5; a_whit.ag = 5; a_whit.ab = 5; a_whit.dr = 250.0; a_whit.dg = 250.0; a_whit.db = 250.0; 
  162.  
  163.    srand(in_seed) ;
  164.  
  165.    w = RINGWEDGE;
  166.  
  167.    d = &dt[0][   0]; d->p.y =  w; d->p.x = -1.0; d->p.z =  0.0; d->seed = rand();
  168.    d = &dt[1][   0]; d->p.y = -w; d->p.x = -1.0; d->p.z =  0.0; d->seed = rand();
  169.    d = &dt[0][ 256]; d->p.y =  w; d->p.x =  0.0; d->p.z = -1.0; d->seed = rand();
  170.    d = &dt[1][ 256]; d->p.y = -w; d->p.x =  0.0; d->p.z = -1.0; d->seed = rand();
  171.    d = &dt[0][ 512]; d->p.y =  w; d->p.x =  1.0; d->p.z =  0.0; d->seed = rand();
  172.    d = &dt[1][ 512]; d->p.y = -w; d->p.x =  1.0; d->p.z =  0.0; d->seed = rand();
  173.    d = &dt[0][ 768]; d->p.y =  w; d->p.x =  0.0; d->p.z =  1.0; d->seed = rand();
  174.    d = &dt[1][ 768]; d->p.y = -w; d->p.x =  0.0; d->p.z =  1.0; d->seed = rand();
  175.    d = &dt[0][1024]; *d = dt[0][0] ; 
  176.    d = &dt[1][1024]; *d = dt[1][0] ; 
  177.  
  178.    for (step=128,dstep=256,stage=1; stage<=8; dstep=step,step>>=1,stage++)
  179.      for (i=step; i<=1024; i+=dstep)  
  180.        fract_mid(i-step,i+step,(flot32)4.0*roughness/(stage*stage)) ;
  181.  
  182.    for (i=0; i<1024; i++)  {
  183.      dt[0][i].valid = 0 ;
  184.      dt[0][i].sur = 0 ;
  185.      dt[0][i].level = -1 ;
  186.      dt[0][i].quadw = -1 ;
  187.      dt[0][i].sidsz = -1 ;
  188.  
  189.      p0 = &dt[0][i+0] ; 
  190.      p1 = &dt[0][i+1] ; 
  191.      p2 = &dt[1][i+0] ; 
  192.      p3 = &dt[1][i+1] ; 
  193.  
  194.      delta0 = fsqrt(p0->p.x*p0->p.x+p0->p.z*p0->p.z);
  195.      delta1 = fsqrt(p1->p.x*p1->p.x+p1->p.z*p1->p.z);
  196.      delta2 = fsqrt(p2->p.x*p2->p.x+p2->p.z*p2->p.z);
  197.      delta3 = fsqrt(p3->p.x*p3->p.x+p3->p.z*p3->p.z);
  198.  
  199.      pp = dt[0][i].pp ;
  200.      pp[0].x = p0->p.x/delta0 ; pp[0].y = p0->p.y ; pp[0].z = p0->p.z/delta0 ;
  201.      pp[2].x = p1->p.x/delta1 ; pp[2].y = p1->p.y ; pp[2].z = p1->p.z/delta1 ;
  202.      pp[4].x = p2->p.x/delta2 ; pp[4].y = p2->p.y ; pp[4].z = p2->p.z/delta2 ;
  203.      pp[6].x = p3->p.x/delta3 ; pp[6].y = p3->p.y ; pp[6].z = p3->p.z/delta3 ;
  204.  
  205.      pp[1].x = 0.999*pp[0].x ; pp[1].y = pp[0].y ; pp[1].z = 0.999*pp[0].z ;
  206.      pp[3].x = 0.999*pp[2].x ; pp[3].y = pp[2].y ; pp[3].z = 0.999*pp[2].z ;
  207.      pp[5].x = 0.999*pp[4].x ; pp[5].y = pp[4].y ; pp[5].z = 0.999*pp[4].z ;
  208.      pp[7].x = 0.999*pp[6].x ; pp[7].y = pp[6].y ; pp[7].z = 0.999*pp[6].z ;
  209.      }
  210.  
  211.    status.status = 1 ;
  212.    status.xi = 0 ;
  213.    status.yi = 0 ;
  214.    status.flag = 0 ;
  215. }
  216.  
  217. /**********************************************************************
  218. *  display_ringworld()  -
  219. **********************************************************************/
  220. void display_ringworld(void) 
  221.  
  222. {  register sint32 i,j,flag,level ;
  223.    register flot32 vian,w ;
  224.    register P5     *p ;
  225.    register V4     *v ;
  226.  
  227.    for (i=0; i<8; i++)
  228.      dbg[i] = 0 ;
  229.  
  230.    /* generate new plates, destroy old plates, draw valid plates */
  231.    for (p=dt[0],j=0; j<1024; p++,j++)  {
  232.      w = (feye.x-p->p.x)*(feye.x-p->p.x) +  (feye.y-p->p.y)*(feye.y-p->p.y) + (feye.z-p->p.z)*(feye.z-p->p.z) ;
  233.  
  234.      if      (w > 1.00000000)
  235.        level = 0+Counter.hw_graphics ;
  236.      else if (w > 0.16000000)
  237.        level = 1+Counter.hw_graphics ;
  238.      else if (w > 0.02560000)
  239.        level = 2+Counter.hw_graphics ;
  240.      else if (w > 0.00409600)
  241.        level = 3+Counter.hw_graphics ;
  242.      else if (w > 0.00065536)
  243.        level = 4+Counter.hw_graphics ;
  244.      else if (w > 0.000065536)
  245.        level = 5+Counter.hw_graphics ;
  246.      else if (w > 0.0000065536)
  247.        level = 6+Counter.hw_graphics ;
  248.      else level = 7+Counter.hw_graphics ;
  249.  
  250.     if (level < 0) level = 0 ;
  251.     if (level > 9) level = 9 ;
  252.  
  253.      if (level != p->level)  {
  254.        p->level = level ;
  255.        for (p->sidsz=1,i=0; i<p->level; p->sidsz<<=1,i++) ;
  256.        destroy_continent(p) ;
  257.        }
  258.  
  259.      if (flag = (~p->valid & BOTHH_TRI))
  260.        create_continent(p,flag,0) ;
  261.  
  262.      if (p->sur)  {
  263.        flag = p->valid & clipp(p) ;
  264.        if (Counter.flags & SHADE_FLAG)
  265.          generate_shades(p,flag) ;
  266.        cpack_continent(p,flag) ;
  267.        }
  268.      }
  269.  
  270.    if ((Counter.flags & DEBUG_FLAG) && (dbg[0]+dbg[1]+dbg[7]))
  271.      printf("Create: %d/%d Display: %02d/%02d Enhance: %d\n",dbg[0],dbg[1],dbg[2],dbg[3],dbg[7]) ;
  272. }
  273.  
  274. /**********************************************************************
  275. *  destroy_ringworld()  -
  276. **********************************************************************/
  277. void destroy_ringworld(void) 
  278.  
  279. {  register sint32 i,j ;
  280.    register P5     *p ;
  281.  
  282.    for (p=dt[0],j=0; j<1024; p++,j++)
  283.      destroy_continent(p) ;
  284. }
  285.  
  286. /**********************************************************************
  287. *  create_continent()  - 
  288. **********************************************************************/
  289. static void create_continent(register P5 *d,register sint32 create,sint32 even)
  290.  
  291. {  register sint32     cstat,i,size ;
  292.    register uint32     hey ;
  293.    register TrigPoint  *sur,*p0,*p1,*p2,*p3 ;
  294.    register P3         *p ;
  295.  
  296.    cstat = clipp(d) ;
  297.  
  298.    if (status.status == 1)
  299.      create &= cstat ;
  300.  
  301.    if (!create)
  302.      return ;
  303.  
  304.    if (!d->sur)  {
  305.      size = 8 + (d->sidsz+1)*(d->sidsz+1)*sizeof(TrigPoint) ;
  306.  
  307.      if (!(sur = (TrigPoint *) malloc(size)))  {
  308.        fprintf(stderr,"ERROR: malloc(%d) failed in create_continent()\n",size) ;
  309.        exit(0) ;
  310.        }
  311.  
  312.      hey = (uint32) sur ;
  313.      if (hey & 8)  {
  314.        hey = (hey + 8) & 0xfffffff0 ;
  315.        sur = (TrigPoint *) hey ;
  316.        d->quadw = 0 ;
  317.        }
  318.      else d->quadw = 1 ;
  319.  
  320.      p0 = sur ;
  321.      p1 = p0 + d->sidsz ;
  322.      p2 = sur + (d->sidsz+1)*d->sidsz ;
  323.      p3 = p2 + d->sidsz ;
  324.  
  325.      p0->plan = (d+0)->p ; 
  326.      p0->seed = (d+0)->seed ; 
  327.      p0->delta = fsqrt(p0->plan.x*p0->plan.x+p0->plan.z*p0->plan.z);
  328.  
  329.      p1->plan = (d+1)->p ; 
  330.      p1->seed = (d+1)->seed ; 
  331.      p1->delta = fsqrt(p1->plan.x*p1->plan.x+p1->plan.z*p1->plan.z);
  332.  
  333.      p2->plan = (d+1025)->p ; 
  334.      p2->seed = (d+1025)->seed ; 
  335.      p2->delta = fsqrt(p2->plan.x*p2->plan.x+p2->plan.z*p2->plan.z);
  336.  
  337.      p3->plan = (d+1026)->p ; 
  338.      p3->seed = (d+1026)->seed ; 
  339.      p3->delta = fsqrt(p3->plan.x*p3->plan.x+p3->plan.z*p3->plan.z);
  340.      }
  341.  
  342.    if (create)  {
  343.      if (create == BOTHH_TRI)
  344.        dbg[0] += 2 ;
  345.      else dbg[1]++ ;
  346.  
  347.      if (!d->sur)
  348.        d->sur = sur ;
  349.  
  350.      land_generation(d,create) ;
  351.  
  352.      water_conversion(d,create) ;
  353.  
  354.      generate_shades(d,create) ;
  355.      d->valid |= create ;
  356.      }
  357.    else if (!d->sur)  {
  358.      hey = (uint32) sur ;
  359.      free(hey - (d->quadw) ? 0 : 8) ;
  360.      }
  361. }
  362.  
  363. /**********************************************************************
  364. *  destroy_continent()  - 
  365. **********************************************************************/
  366. static void destroy_continent(register P5 *p)
  367.  
  368. {  register uint32 hey ;
  369.   
  370.    if (p->sur)  {
  371.      hey = (uint32) p->sur ;
  372.  
  373.      free(hey - (p->quadw) ? 0 : 8) ;
  374.  
  375.      p->valid =  0 ;
  376.      p->sur   =  0 ;
  377.      p->quadw =  0 ;
  378.      }
  379. }
  380.  
  381. /**********************************************************************
  382. *  land_generation()  -
  383. **********************************************************************/
  384. static void land_generation(P5 *d,register sint32 triflag)
  385.  
  386. {  register sint32    stage,step,dstep,i,j,s,q,sp ;
  387.    register flot32    x,y,z,w,rg ;
  388.    register TrigPoint *c,*c1,*c2,*c3,*c4 ;
  389.    register P4        p ;
  390.    register TrigPoint *sur ;
  391.  
  392.    sur = d->sur ;
  393.  
  394.    step = 1 << (d->level-1) ;
  395.    rg = roughness/((1.0+C)*16384.0) ;
  396.  
  397.    for (dstep=step+step,stage=1; stage<=d->level; rg*=0.50,dstep=step,step>>=1,stage++)  {
  398.      sp = step*(d->sidsz+1) ;
  399.  
  400.      for (i=dstep; i<=d->sidsz; i+=dstep)  {
  401.        c1 = sur + i-dstep ; 
  402.        c2 = sur + i ; 
  403.        c3 = sur + dstep*(d->sidsz+1) + i - dstep ; 
  404.        c4 = sur + dstep*(d->sidsz+1) + i ; 
  405.  
  406.        for (j=step; j<=d->sidsz; j+=dstep)  {
  407.          q = d->sidsz + step - i - j ;
  408.  
  409.          if ((triflag & LOWER_TRI) && (q >= 0))  {
  410.            c = c2-step ;
  411.            SUBDIVIDE(c1,c2,c) ;
  412.            c = c1+sp ;
  413.            SUBDIVIDE(c1,c3,c) ;
  414.            c = c1+sp+step ;
  415.            SUBDIVIDE(c2,c3,c) ;
  416.            }
  417.  
  418.          if ((triflag & UPPER_TRI) && (q <= 0)) {
  419.            c = c4-step ;
  420.            SUBDIVIDE(c3,c4,c) ;
  421.            c = c2+sp ;
  422.            SUBDIVIDE(c2,c4,c) ;
  423.            c = c1+sp+step ;
  424.            SUBDIVIDE(c2,c3,c) ;
  425.            }
  426.  
  427.          c1 += sp+sp ;
  428.          c2 += sp+sp ;
  429.          c3 += sp+sp ;
  430.          c4 += sp+sp ;
  431.          }
  432.        }
  433.      }
  434. }
  435.  
  436. /**********************************************************************
  437. *  water_conversion()  - 
  438. **********************************************************************/
  439. static void water_conversion(P5 *d,register sint32 triflag) 
  440.  
  441. {  register sint32    i,j,q ;
  442.    register flot32    w ;
  443.    register TrigPoint *sur,*trg ;
  444.  
  445.    sur = d->sur ;
  446.  
  447.    for (i=0; i<=d->sidsz; i++) 
  448.      for (trg=sur+(d->sidsz+1)*i,j=0; j<=d->sidsz; trg++,j++)  {
  449.        q = d->sidsz-i-j ;
  450.  
  451.        if (((triflag & LOWER_TRI) && (q >= 0)) || ((triflag & UPPER_TRI) && (q <= 0)))  {
  452.          w = trg->delta ;
  453.  
  454.          if (w >= LEVEL_SEA)  {
  455.            trg->plan.x /= w ;
  456.            trg->plan.z /= w ;
  457.            trg->label = MAT_SEABLUE ;
  458.            }
  459.          else if (w < LEVEL_SNOW)
  460.            trg->label = MAT_WHITE ;
  461.          else trg->label = MAT_DIRT ;
  462.          }
  463.        }
  464. }
  465.  
  466. /**********************************************************************
  467. *  generate_shades()  - 
  468. **********************************************************************/
  469. static void generate_shades(register P5 *d,register sint32 triflag) 
  470.  
  471. {  register sint32    i,j,r,g,b,q;
  472.    register flot32    x,y,z,w,daylight,theta,delta ;
  473.    register V3        v1,v2,lit ;
  474.    register TrigPoint *sur,*p00,*p10 ;
  475.    register C6        *cc,cl ;
  476.    register P3        *p ;
  477.  
  478.    sur = d->sur ;
  479.  
  480.    lit.x = sur->plan.x ;
  481.    lit.y = 0.0 ;
  482.    lit.z = sur->plan.z ;
  483.    w = -fsqrt(lit.x*lit.x + lit.z*lit.z) ;
  484.    lit.x /= w ;
  485.    lit.z /= w ;
  486.  
  487.    delta = 0.5*Counter.D / 9.037;
  488.    delta = 366.0 - 360.0*(delta - (long)delta) ;
  489.  
  490.    for (i=0; i<d->sidsz; i++)  {
  491.       p00 = sur + (d->sidsz+1)*(i) ;
  492.       p10 = sur + (d->sidsz+1)*(i+1) ;
  493.  
  494.       for (j=0; j<d->sidsz; p00++,p10++,j++)  {
  495.         q = d->sidsz - i - j ;
  496.  
  497.         theta = RTOD*(M_PI + atan2(p00->plan.x,p00->plan.z)) + delta;
  498.         theta /= 12.0;
  499.         r = theta;
  500.         if (r & 1)
  501.           daylight = 1.0;
  502.         else daylight = 0.0;
  503.  
  504.         if (((triflag & LOWER_TRI) && (q >= 1)) || ((triflag & UPPER_TRI) && (q <= 0)))  {
  505.           v1.x = (p00+1)->plan.x - p00->plan.x ;
  506.           v1.y = (p00+1)->plan.y - p00->plan.y ;
  507.           v1.z = (p00+1)->plan.z - p00->plan.z ;
  508.  
  509.           v2.x = p10->plan.x - p00->plan.x ;
  510.           v2.y = p10->plan.y - p00->plan.y ;
  511.           v2.z = p10->plan.z - p00->plan.z ;
  512.        
  513.           x = v2.y * v1.z - v1.y * v2.z ;
  514.           y = v1.x * v2.z - v2.x * v1.z ;
  515.           z = v2.x * v1.y - v1.x * v2.y ;
  516.           w = x*lit.x + y*lit.y + z*lit.z ;
  517.  
  518.           if (Counter.flags & FRACT_FLAG)  {
  519.             r = p00->label + (p00+1)->label + p10->label ;
  520.             if (r == SUM_SEABLUE)
  521.               cc = &a_seab ;
  522.             else if (r == SUM_WHITE)
  523.               cc = &a_whit ;
  524.             else cc = &a_dirt ;
  525.  
  526.             r = cc->ar ;
  527.             g = cc->ag ;
  528.             b = cc->ab ;
  529.  
  530.             if (w > 0.0)  {
  531.               w *= daylight/fsqrt(x*x+y*y+z*z) ;
  532.               r += cc->dr * w;
  533.               g += cc->dg * w;
  534.               b += cc->db * w;
  535.               }
  536.             }
  537.           else  {
  538.             cl.dr = ((p00->seed    ) & 0xff) + (((p00+1)->seed    ) & 0xff) + ((p10->seed    ) & 0xff) ;
  539.             cl.dg = ((p00->seed>> 8) & 0xff) + (((p00+1)->seed>> 8) & 0xff) + ((p10->seed>> 8) & 0xff) ;
  540.             cl.db = ((p00->seed>>16) & 0xff) + (((p00+1)->seed>>16) & 0xff) + ((p10->seed>>16) & 0xff) ;
  541.             r = 0.015 * cl.dr ;
  542.             g = 0.015 * cl.dg ;
  543.             b = 0.015 * cl.db ;
  544.  
  545.             if (w > 0.0)  {
  546.               w *= daylight/(3.0*fsqrt(x*x+y*y+z*z)) ;
  547.               r += cl.dr * w;
  548.               g += cl.dg * w;
  549.               b += cl.db * w;
  550.               }
  551.             }
  552.  
  553.           p00->cpack1 = (r<<24) | (g<<16) | (b<<8) | 0xff ;
  554.           }
  555.  
  556.         if (((triflag & LOWER_TRI) && (q > 1)) || ((triflag & UPPER_TRI) && (q <= 1)))  {
  557.           v1.x = p10->plan.x - (p10+1)->plan.x ;
  558.           v1.y = p10->plan.y - (p10+1)->plan.y ;
  559.           v1.z = p10->plan.z - (p10+1)->plan.z ;
  560.  
  561.           v2.x = (p00+1)->plan.x - (p10+1)->plan.x ;
  562.           v2.y = (p00+1)->plan.y - (p10+1)->plan.y ;
  563.           v2.z = (p00+1)->plan.z - (p10+1)->plan.z ;
  564.  
  565.           x = v2.y * v1.z - v1.y * v2.z ;
  566.           y = v1.x * v2.z - v2.x * v1.z ;
  567.           z = v2.x * v1.y - v1.x * v2.y ;
  568.           w = x*lit.x + y*lit.y + z*lit.z ;
  569.  
  570.           if (Counter.flags & FRACT_FLAG)  {
  571.             r = (p10+1)->label + (p00+1)->label + p10->label ;
  572.             if (r == SUM_SEABLUE)
  573.               cc = &a_seab ;
  574.             else if (r == SUM_WHITE)
  575.               cc = &a_whit ;
  576.             else cc = &a_dirt ;
  577.  
  578.             r = cc->ar ;
  579.             g = cc->ag ;
  580.             b = cc->ab ;
  581.  
  582.             if (w > 0.0)  {
  583.               w *= daylight/fsqrt(x*x+y*y+z*z) ;
  584.               r += cc->dr * w;
  585.               g += cc->dg * w;
  586.               b += cc->db * w;
  587.               }
  588.             }
  589.           else  {
  590.             cl.dr = (((p10+1)->seed    ) & 0xff) + (((p00+1)->seed    ) & 0xff) + ((p10->seed    ) & 0xff) ;
  591.             cl.dg = (((p10+1)->seed>> 8) & 0xff) + (((p00+1)->seed>> 8) & 0xff) + ((p10->seed>> 8) & 0xff) ;
  592.             cl.db = (((p10+1)->seed>>16) & 0xff) + (((p00+1)->seed>>16) & 0xff) + ((p10->seed>>16) & 0xff) ;
  593.             r = 0.015 * cl.dr ;
  594.             g = 0.015 * cl.dg ;
  595.             b = 0.015 * cl.db ;
  596.  
  597.             if (w > 0.0)  {
  598.               w *= daylight/(3.0*fsqrt(x*x+y*y+z*z)) ;
  599.               r += cl.dr * w;
  600.               g += cl.dg * w;
  601.               b += cl.db * w;
  602.               }
  603.             }
  604.  
  605.           p00->cpack2 = (r<<24) | (g<<16) | (b<<8) | 0xff ;
  606.           }
  607.         }
  608.       }
  609. }
  610.  
  611. /**********************************************************************
  612. *  clipp()  -
  613. **********************************************************************/
  614. static sint32 clipp(register P5 *d)
  615.  
  616. {  register sint32 i,j ;
  617.    register uint32 flag,resu,mask ;
  618.    register P3     *p ; 
  619.    register V4     *c ; 
  620.  
  621.    for (c=plum,resu=i=0; i<NUM_CLIP_PLANES; c++,i++)  {
  622.      for (mask=1,p=d->pp,flag=0,j=0; j<8; mask<<=1,p++,j++)
  623.        if (c->x*p->x + c->y*p->y + c->z*p->z + c->w < 0.0)
  624.          flag |= mask ;
  625.  
  626.      if (flag == 0xff)
  627.        return(0) ; 
  628.      if ((flag&0x3f) == 0x3f) 
  629.        resu |= LOWER_TRI ;
  630.      if ((flag&0xfc) == 0xfc)
  631.        resu |= UPPER_TRI ;
  632.      }
  633.  
  634.    return(BOTHH_TRI) ;
  635. }
  636.  
  637. /**********************************************************************
  638. *  cpack_continent()  -
  639. **********************************************************************/
  640. static void cpack_continent(register P5 *d,register uint32 flag)
  641.  
  642. {  register sint32     i,j ;
  643.    register TrigPoint  *sur,*trp,*srp ;
  644.  
  645.    sur = d->sur ;
  646.  
  647.    if ((uint32)sur & 0x0f)  {
  648.      printf("Error: data is not quad-word aligned!\n") ;
  649.      exit() ;
  650.      }
  651.  
  652.    switch (flag)  {
  653.      case         0 : return ;
  654.                       break ;
  655.  
  656.      case BOTHH_TRI : for (srp=sur,j=d->sidsz; j>0; srp+=d->sidsz+1,j--)  {
  657.                         glBegin(GL_TRIANGLE_STRIP) ;
  658.                         glVertex3fv(&srp->plan.x) ;
  659.                         glVertex3fv(&(srp+d->sidsz+1)->plan.x) ;
  660.                  
  661.                         for (trp=srp,i=d->sidsz; i>0; trp++,i--)  {
  662.                           glColor4ubv((unsigned char*)&trp->cpack1) ;
  663.                           glVertex3fv(&(trp+1)->plan.x) ;
  664.  
  665.                           glColor4ubv((unsigned char*)&trp->cpack2) ;
  666.                           glVertex3fv(&(trp+d->sidsz+2)->plan.x) ;
  667.                           }
  668.  
  669.                         glEnd() ;
  670.                         }
  671.  
  672.                       dbg[2]+=2 ;
  673.                       break ;
  674.  
  675.      case LOWER_TRI : for (srp=sur,j=d->sidsz; j>0; srp+=d->sidsz=1,j--)  {
  676.                         glBegin(GL_TRIANGLE_STRIP) ;
  677.                         glVertex3fv(&srp->plan.x) ;
  678.                         glVertex3fv(&(srp+d->sidsz+1)->plan.x) ;
  679.                  
  680.                         for (trp=srp,i=j-1; i>0; i--)  {
  681.                           glColor4ubv((unsigned char*)&trp->cpack1) ;
  682.                           glVertex3fv(&(trp+1)->plan.x) ;
  683.                  
  684.                           glColor4ubv((unsigned char*)&trp->cpack2) ;
  685.                           glVertex3fv(&(trp+d->sidsz+2)->plan.x) ;
  686.                           trp++ ;
  687.                           }
  688.                  
  689.                         glColor4ubv((unsigned char*)&trp->cpack1) ;
  690.                         glVertex3fv(&(trp+1)->plan.x) ;
  691.                         glEnd() ;
  692.                         }
  693.  
  694.                       dbg[3]++ ;
  695.                       break ;
  696.  
  697.      case UPPER_TRI : for (srp=(sur+(d->sidsz+1)*d->sidsz),j=d->sidsz; j>0; srp-=d->sidsz+1,j--)  {
  698.                         glBegin(GL_TRIANGLE_STRIP) ;
  699.                         glVertex3fv(&srp->plan.x) ;
  700.                         glVertex3fv(&(srp-d->sidsz-1)->plan.x) ;
  701.                  
  702.                         for (trp=srp,i=j-1; i>0; i--)  {
  703.                           glColor4ubv((unsigned char*)&(trp-d->sidsz-2)->cpack2) ;
  704.                           glVertex3fv(&(trp-1)->plan.x) ;
  705.                  
  706.                           glColor4ubv((unsigned char*)&(trp-d->sidsz-2)->cpack1) ;
  707.                           glVertex3fv(&(trp-d->sidsz-2)->plan.x) ;
  708.                           trp-- ;
  709.                           }
  710.                  
  711.                         glColor4ubv((unsigned char*)&(trp-d->sidsz-2)->cpack2) ;
  712.                         glVertex3fv(&(trp-1)->plan.x) ;
  713.                         glEnd() ;
  714.                         }
  715.  
  716.                       dbg[3]++ ;
  717.                       break ;
  718.  
  719.      default        : printf("Error: cpack_continent(%d)\n",flag) ;
  720.                       exit(0) ;
  721.                       break ;
  722.      }
  723. }
  724.  
  725. /**********************************************************************
  726. *  p_trigpoint()  -
  727. **********************************************************************/
  728. static void p_trigpoint(TrigPoint *t) 
  729.  
  730. {
  731.    printf("T: %7.4f %7.4f %7.4f %6.4f %06d %1d 0x%08x 0x%08x\n",
  732.               t->plan.x,t->plan.y,t->plan.z,t->delta,t->seed,t->label,t->cpack1,t->cpack2) ;
  733. }
  734.  
  735. /**********************************************************************
  736. *  p_continent()  -
  737. **********************************************************************/
  738. static void p_continent(P5 *d) 
  739.  
  740. {  sint32 i,j ;
  741.    register TrigPoint *sur ;
  742.  
  743.    printf("Continent: 0x%08x\n",d->sur) ;
  744.  
  745.    for (i=0; i<=d->sidsz; i++)
  746.      for (j=0; j<=d->sidsz; j++)  {
  747.         printf("%d %d:",i,j) ;
  748.         p_trigpoint(d->sur + (d->sidsz+1)*i+j) ;
  749.         }
  750. }
  751.  
  752.